/*
 *  ConnectionHandler.cpp
 *  SaskuServer
 *
 *  Created by Einar Pius on 13/07/2008.
 *  Copyright 2008 __MyCompanyName__. All rights reserved.
 *
 */

#include "ConnectionHandler.h"
#include <Poco/NObserver.h>
#include <Poco/Util/Application.h>

using Poco::AutoPtr;
using Poco::NObserver;
using Poco::Net::ErrorNotification;
using Poco::Net::ReadableNotification;
using Poco::Net::ShutdownNotification;
using Poco::Net::StreamSocket;
using Poco::Net::SocketReactor;
using Poco::Net::TimeoutNotification;
using Poco::Util::Application;

ConnectionHandler::ConnectionHandler(const StreamSocket& socket, SocketReactor& reactor)
:	reactor(reactor),
	socket(socket)
{
	Application::instance().logger().information("Connection from " + socket.peerAddress().toString() + " accepted.");
	reactor.addEventHandler(socket, NObserver<ConnectionHandler, ErrorNotification>(*this, &ConnectionHandler::onError));
	reactor.addEventHandler(socket, NObserver<ConnectionHandler, ReadableNotification>(*this, &ConnectionHandler::onReadable));
	reactor.addEventHandler(socket, NObserver<ConnectionHandler, ShutdownNotification>(*this, &ConnectionHandler::onShutdown));
	reactor.addEventHandler(socket, NObserver<ConnectionHandler, TimeoutNotification>(*this, &ConnectionHandler::onTimeout));
}

ConnectionHandler::~ConnectionHandler()
{
	reactor.removeEventHandler(socket, NObserver<ConnectionHandler, ErrorNotification>(*this, &ConnectionHandler::onError));
	reactor.removeEventHandler(socket, NObserver<ConnectionHandler, ReadableNotification>(*this, &ConnectionHandler::onReadable));
	reactor.removeEventHandler(socket, NObserver<ConnectionHandler, ShutdownNotification>(*this, &ConnectionHandler::onShutdown));
	reactor.removeEventHandler(socket, NObserver<ConnectionHandler, TimeoutNotification>(*this, &ConnectionHandler::onTimeout));
}

void ConnectionHandler::onError(const AutoPtr<ErrorNotification>&)
{
	Application::instance().logger().information("Connection error with client " + socket.peerAddress().toString() + ". Closing connection.");
	delete this;
}

void ConnectionHandler::onReadable(const AutoPtr<ReadableNotification>&)
{
	std::string msg;
	if (!socket.receiveMessage(msg))
	{
		Application::instance().logger().information("Connection from " + socket.peerAddress().toString() + " closed by client.");
		delete this;
	}
}

void ConnectionHandler::onShutdown(const AutoPtr<ShutdownNotification>&)
{
	Application::instance().logger().information("Connection to " + socket.peerAddress().toString() + " shut down.");
	delete this;
}

void ConnectionHandler::onTimeout(const AutoPtr<TimeoutNotification>&)
{
	Application::instance().logger().information("Connection timeout from " + socket.peerAddress().toString() + ". Closing connection.");
	delete this;
}
